package io.gitee.kotle.android.utils

import android.database.Cursor
import android.net.Uri
import android.os.CancellationSignal
import android.provider.ContactsContract
import android.provider.MediaStore
import androidx.core.database.getStringOrNull
import io.gitee.kotle.android.BaseGlobalConst.app
import org.json.JSONArray
import org.json.JSONObject

/**
 * 查询公共数据库
 */
inline fun contentResolverQuery(
    uri: Uri,
    projection: Array<String>? = null,
    selection: String? = null,
    selectionArgs: Array<String>? = null,
    sortOrder: String? = null,
    cancellationSignal: CancellationSignal? = null,
    beforeBlock: ((Cursor) -> Unit) = {},
    eachBlock: ((Cursor) -> Unit)
) {
    app.contentResolver.query(
        uri,
        projection,
        selection,
        selectionArgs,
        sortOrder,
        cancellationSignal
    )?.let {
        beforeBlock.invoke(it)
        while (it.moveToNext()) {
            eachBlock.invoke(it)
        }
        it.close()
    }
}

/**
 * 查询视频类型
 */
inline fun contentResolverQueryVideo(
    projection: Array<String>? = null,
    selection: String? = null,
    selectionArgs: Array<String>? = null,
    sortOrder: String? = null,
    cancellationSignal: CancellationSignal? = null,
    beforeBlock: ((Cursor) -> Unit) = {},
    eachBlock: ((Cursor) -> Unit)
) {
    contentResolverQuery(
        MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
        projection, selection, selectionArgs, sortOrder, cancellationSignal, beforeBlock, eachBlock
    )
}

/**
 * 查询图片类型
 */
inline fun contentResolverQueryImages(
    projection: Array<String>? = null,
    selection: String? = null,
    selectionArgs: Array<String>? = null,
    sortOrder: String? = null,
    cancellationSignal: CancellationSignal? = null,
    beforeBlock: ((Cursor) -> Unit) = {},
    eachBlock: ((Cursor) -> Unit)
) {
    contentResolverQuery(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        projection, selection, selectionArgs, sortOrder, cancellationSignal, beforeBlock, eachBlock
    )
}

/**
 * 查询音频类型
 */
inline fun contentResolverQueryAudio(
    projection: Array<String>? = null,
    selection: String? = null,
    selectionArgs: Array<String>? = null,
    sortOrder: String? = null,
    cancellationSignal: CancellationSignal? = null,
    beforeBlock: ((Cursor) -> Unit) = {},
    eachBlock: ((Cursor) -> Unit)
) {
    contentResolverQuery(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        projection, selection, selectionArgs, sortOrder, cancellationSignal, beforeBlock, eachBlock
    )
}

/**
 * 查询下载类型
 */
inline fun contentResolverQueryDownloads(
    projection: Array<String>? = null,
    selection: String? = null,
    selectionArgs: Array<String>? = null,
    sortOrder: String? = null,
    cancellationSignal: CancellationSignal? = null,
    beforeBlock: ((Cursor) -> Unit) = {},
    eachBlock: ((Cursor) -> Unit)
) {
    contentResolverQuery(
        if (!isExternalStorageLegacy) {
            MediaStore.Downloads.EXTERNAL_CONTENT_URI
        } else {
            MediaStore.Files.getContentUri("external")
        },
        projection, selection, selectionArgs, sortOrder, cancellationSignal, beforeBlock, eachBlock
    )
}

/**
 * 获取联系人数据
 */
fun getSimpleContacts(): JSONArray {
    val result = JSONArray()
    contentResolverQuery(ContactsContract.Contacts.CONTENT_URI) {
        val info = JSONObject()
        //数据库id
        val contactId = it.getStringOrNull(it.getColumnIndex(ContactsContract.Contacts._ID))
        it.getStringOrNull(it.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))
            ?.let { name ->
                info.put("name", name)
            }
        //查询电话号码
        val phoneList = JSONArray()
        contentResolverQuery(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
            "${ContactsContract.CommonDataKinds.Phone.CONTACT_ID}=${contactId}", null, null
        ) { phoneCursor ->
            phoneCursor.getStringOrNull(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
                ?.let { phone ->
                    phoneList.put(phone)
                }
        }
        info.put("phone", phoneList)
        result.put(info)
    }
    return result
}